package com.adkun.markdown.markdown;

import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class MdTree implements NodeTypes {

    private class Node implements NodeTypes {
        int type;
        LinkedList<Node> children = new LinkedList<>();
        String content;
    }

    Node root = new Node();

    /**
     * 生成AST
     *
     * @param md
     */
    public void generateMdTree(ArrayList<String> md) {
        for (int i = 0; i < md.size(); i++) {
            StringBuilder sb = new StringBuilder(md.get(i));
            int type = getLineType(sb);
            if (type == CODE_BLOCK) {
                // 代码块
                i++;
                Node codeNode = new Node();
                codeNode.type = CODE_BLOCK;
                root.children.add(codeNode);
                while (i < md.size() && getLineType(new StringBuilder(md.get(i))) != CODE_BLOCK) {
                    parseLine(new StringBuilder(md.get(i)), codeNode, 1);
                }
            } else {
                parseLine(new StringBuilder(md.get(i)), root, 0);
            }
        }
    }

    /**
     * 处理一行
     *
     * @param line
     * @param mode 0：普通模式 1：代码块模式
     */
    private void parseLine(StringBuilder line, Node node, int mode) {
        if (mode == 1) {

        }
        while (line.length() > 0) {
            int type = getLineType(line);
            // 检查当前节点最后一个子节点是否符合该type
            if (node.children.isEmpty()) {
                // 无子节点，创建
                Node newNode = new Node();
                newNode.type = type;
                if (type == WAIT_FOR_PARSE) {
                    newNode.content = line.toString();
                }
                removeLineType(line, type);
            } else {
                // 有子节点，检查是否相符
                int lastChildrenType = node.children.getLast().type;
                if (lastChildrenType == type) {
                    // 相符
                    if (type == WAIT_FOR_PARSE) {
                        // 避免内容覆盖
                        Node newNode = new Node();
                        newNode.type = type;
                        newNode.content = line.toString();
                        removeLineType(line, type);
                    } else {
                        // 当前节点下移
                        node = node.children.getLast();
                        removeLineType(line, type);
                    }
                } else {
                    // 不相符
                    Node newNode = new Node();
                    newNode.type = type;
                    if (type == WAIT_FOR_PARSE) {
                        newNode.content = line.toString();
                    }
                    removeLineType(line, type);
                }
            }
        }
    }

    /**
     * 处理一行首类型
     *
     * @param str
     */
    private int getLineType(StringBuilder str) {
        int len = str.length();
        if (len >= 4) {
            String prefix = str.substring(0, 4);
            char preCh = prefix.charAt(0);
            char preCh2 = prefix.charAt(1);
            char preCh3 = prefix.charAt(2);
            char preCh4 = prefix.charAt(3);
            if (Character.isDigit(preCh) && Character.isDigit(preCh2)
                    && preCh3 == '.' && preCh4 == ' ') {
                return ORDERED_LIST;
            }
            if ("    ".equals(prefix)) {
                // 缩进
                return TAB;
            }
        }
        if (len >= 3) {
            String prefix = str.substring(0, 3);
            char preCh = prefix.charAt(0);
            char preCh2 = prefix.charAt(1);
            char preCh3 = prefix.charAt(2);
            if ("```".equals(prefix)) {
                // 代码块
                return CODE_BLOCK;
            }
            if (Character.isDigit(preCh) && preCh2 == '.' && preCh3 == ' ') {
                // 有序列表
                return ORDERED_LIST;
            }
            if ("---".equals(prefix)) {
                // 水平分隔线
                return HORIZON;
            }
        }
        if (len >= 2) {
            String prefix = str.substring(0, 2);
            if ("> ".equals(prefix)) {
                // 引用块
                return QUOTE_BLOCK;
            }

            char preCh = prefix.charAt(0);
            char preCh2 = prefix.charAt(1);
            if (preCh == '*' || preCh == '+' || preCh == '-') {
                if (preCh2 == ' ') {
                    // 无序列表
                    return UNORDERED_LIST;
                }
            }

            if (prefix.charAt(0) == '#') {
                // 标题
                int count = 0;
                boolean ok = false;
                for (int i = 0; i < str.length(); i++) {
                    char ch = str.charAt(i);
                    if (ch == '#') {
                        count++;
                    } else if (ch == ' ') {
                        ok = true;
                    }
                }
                if (ok) {
                    switch (count) {
                        case 1:
                            return TITLE_ONE;
                        case 2:
                            return TITLE_TWO;
                        case 3:
                            return TITLE_THREE;
                        case 4:
                            return TITLE_FOUR;
                        case 5:
                            return TITLE_FIVE;
                        case 6:
                            return TITLE_SIX;
                        default:
                            return WAIT_FOR_PARSE;
                    }
                }
            }
        }
        // 空行
        if (len == 0) {
            return SPACE_LINE;
        } else if (len == 1) {
            if (str.charAt(0) == ' ' || str.charAt(0) == '\n') {
                return SPACE_LINE;
            }
        }
        return WAIT_FOR_PARSE;
    }

    private void removeLineType(StringBuilder line, int type) {
        if (type == TITLE_ONE) {
            line.delete(0, 2);
        } else if (type == TITLE_TWO) {
            line.delete(0, 3);
        } else if (type == TITLE_THREE) {
            line.delete(0, 4);
        } else if (type == TITLE_FOUR) {
            line.delete(0, 5);
        } else if (type == TITLE_FIVE) {
            line.delete(0, 6);
        } else if (type == TITLE_SIX) {
            line.delete(0, 7);
        } else if (type == ORDERED_LIST) {
            line.delete(0, 3);
        } else if (type == UNORDERED_LIST) {
            line.delete(0, 2);
        } else if (type == QUOTE_BLOCK) {
            line.delete(0, 2);
        } else if (type == CODE_BLOCK) {
            line.delete(0, line.length());
        } else if (type == TAB) {
            line.delete(0, 4);
        } else if (type == NORMAL_LINE || type == WAIT_FOR_PARSE) {
            line.delete(0, line.length());
        }
    }

}
